---
title: 'Quickstart (2/2): Embed in your app'
sidebarTitle: '(2/2) Embed in your app'
description: '⏱️ 1 hour to complete'
---

<Frame caption="Authorization overview.">
  <img src="/images/diagrams/auth.png"/>
</Frame>

<Steps>
  <Step title="Generate a session token (backend)">
    In **your backend**, set up an API endpoint that your frontend will call before each authorization attempt to retrieve a session token from Nango.

    Here's an example of how your backend can retrieve a session token from Nango ([API](/reference/api/connect/sessions/create) / [Node SDK](/reference/sdks/node#create-a-connect-session) references):

    <Tabs>

    <Tab title="Node">

    ```ts
    import { Nango } from '@nangohq/node';

    const nango = new Nango({ secretKey: process.env['<NANGO-SECRET-KEY>'] });

    api.post('/sessionToken', (req, res) => {
      // Ask Nango for a secure token
      const res = await nango.createConnectSession({
        end_user: {
          id: '<END-USER-ID>',
          email: '<OPTIONAL-END-USER-EMAIL>',
          display_name: '<OPTIONAL-END-USER-DISPLAY-NAME>',
          tags: { organizationId: '<ORGANIZATION-ID>' }
        },
        allowed_integrations: ['<INTEGRATION-ID>'],
      });

      // Send this token back to your frontend
      res.status(200).send({
        sessionToken: res.data.token
      });
    });
    ```
    </Tab>

    <Tab title="cURL">

    ```bash
    curl --request POST \
      --url https://api.nango.dev/connect/sessions \
      --header 'Authorization: Bearer <NANGO-SECRET-KEY>' \
      --header 'Content-Type: application/json' \
      --data '{
        "end_user": {
          "id": "<REQUIRED-END-USER-ID>",
          "email": "<OPTIONAL-END-USER-EMAIL>",
          "display_name": "<OPTIONAL-END-USER-DISPLAY-NAME>"
        },
        "organization": {
          "id": "<OPTIONAL-ORG-ID>",
          "display_name": "<OPTIONAL-ORG-DISPLAY-NAME>"
        },
        "allowed_integrations": [
          "<INTEGRATION-ID>"
        ]
      }'

    ```

    </Tab>

    </Tabs>

    <Accordion title="ℹ️ Details on end user and organization information">
      The `end_user` and `organization` information fields help identify which connection belongs to which end user and organization. This information is also used for display purposes in the Nango UI and, in some cases, for custom billing plans.

      <Info>
        The `end_user.id` is required. Pass in your internal ID of the user who initiated the authorization flow. This ID, and potentially the `tags`, are necessary for reconciling the connection details that your backend receives from Nango after the connection is created (as described in the [section 3](/implementation-guides/api-auth/implement-api-auth#3-listen-for-webhooks-%26-save-the-connection-id-backend)).
      </Info>

      <Info>
        It's possible that the end use's email in your app will not match the email they use to connect their external account, which is fine.
      </Info>

      <Info>
      **Organization-level connections**

      In some cases, a connection belongs to an organization rather than a user. In such cases, fill in the relevant organization information and use a place holder for the required `end_user.id` (or use the information of the user who initiated the authorization flow). 
      </Info>  

    </Accordion>
  </Step>
  <Step title="Embed the auth flow (frontend)">
    In **your frontend**, load the Nango frontend SDK, retrieve the session token from the backend, and trigger the authorization flow.

    <Frame caption="Nango's default authorization UI.">
      <img src="/images/screenshots/connect-ui.gif" />
    </Frame>

    <Tip>
      You can override the Nango default UI by [following this guide](/implementation-guides/api-auth/customize-connect-ui)).
    </Tip>

    ```js
    import Nango from '@nangohq/frontend';

    const nango = new Nango();
    const connect = nango.openConnectUI({
      onEvent: (event) => {
        if (event.type === 'close') {
          // Handle modal closed.
        } else if (event.type === 'connect') {
          // Handle auth flow successful.
        }
      },
    });

    const res = await fetch('/sessionToken', { method: 'POST' }); // Retrieve the session token from your backend.
    connect.setSessionToken(res.sessionToken); // A loading indicator is shown until this is set.
    ```

    ([Frontend SDK reference](/reference/sdks/frontend#connect-using-nango-connect-ui))
  </Step>
  <Step title="Listen for webhooks (backend)">
    Upon successful authorization, Nango will send a webhook to your backend with the connection ID. This connection ID, a UUID generated by Nango, is required to manage the connection and access its credentials & data. **So you need to persist it in your database.**

    To process Nango webhooks:
    1. Go to the [Environment Settings](https://app.nango.dev/dev/environment-settings) tab in the Nango UI
    2. Specify a _Webhook URL_ where Nango should send notifications
    3. Enable the _Send New Connection Creation Webhooks_ option
    4. Create the specified route in your backend to handle Nango webhooks

    Successful authorization webhooks sent by Nango are `POST` requests with the following JSON body:
    ```json
    {
        "type": "auth",
        "operation": "creation",
        "success": true,
        "connectionId": "<CONNECTION-ID>",
        "endUser": {
          "endUserId": "<END-USER-ID>",
          "tags": { "organizationId": "<ORGANIZATION-ID>" }
        },
        ...
    }
    ```

    For each successful authorization, persist the `connectionId` value alongside its corresponding user or organization.
  </Step>
</Steps>

Congrats 🎉 You can now run the authorization flow directly from your app and verify that a connection is created in the [Connections](https://app.nango.dev/dev/connections) tab.

Troubleshoot errors in the [Logs](https://app.nango.dev/dev/logs) tab.

<Tip>
    **Questions, problems, feedback?** Please reach out in the [Slack community](https://nango.dev/slack).
</Tip>